unit tools;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, DBGrids, StdCtrls, DBCtrls, ComCtrls,Mask, DBCGrids;

type TSortInfo=Record
    col:Integer;
    asc:Boolean;
  End;
  TMoveSG = class(TCustomGrid);


function CompareValues(const S1, S2 : String;asc:Boolean): Integer;
function CompareInt(i1, i2: Integer): Integer;
procedure SortGridByCols(Grid: TStringGrid;  Fixed: Boolean);

const colorder: array[0..3] of TSortInfo =
    ((col: 6; asc: false),
     (col: 5; asc: false),
     (col: 3; asc: false),
     (col: 4; asc: true)
     );


implementation


// Zahlen vergleichen
function CompareInt(i1, i2: Integer): Integer;
// Result: -1 if i1 < i2, 1 if i1 > i2, 0 if i1 = i2
begin
  if i1 < i2 then
    Result := -1
  else if i1 > i2 then
    Result := 1
  else
    Result := 0;
end;

// Strings vergleichen
function CompareValues(const S1, S2 : String;asc:Boolean): Integer;
var
  V1, V2 : Integer;
  C1, C2 : Integer;
begin
  Val(S1, V1, C1);
  Val(S2, V2, C2);
  if (C1 = 0) and (C2 = 0) then  // Wenn beides Zahlen
     Result := CompareInt(V1, V2)
  else  // sonst wenn String/String od. String/Zahl
     Result := AnsiCompareStr(S1, S2);
  if not Asc then Result := Result * -1;

end;

procedure SortGridByCols(Grid: TStringGrid; Fixed: Boolean);
var
  I, J, FirstRow: Integer;
  Sorted: Boolean;

  function Sort(Row1, Row2: Integer): Integer;
  var
    C: Integer;
  begin
    C := 0;
    Result := CompareValues(Grid.Cols[ColOrder[C].col][Row1], Grid.Cols[ColOrder[C].col][Row2],ColOrder[C].asc);
    if Result = 0 then
    begin
      Inc(C);
      while (C <= High(ColOrder)) and (Result = 0) do
      begin
        Result := CompareValues(Grid.Cols[ColOrder[C].col][Row1], Grid.Cols[ColOrder[C].col][Row2],ColOrder[C].asc);
        Inc(C);
      end;
    end;
  end;

begin

  for I := 0 to High(ColOrder) do
    if (ColOrder[I].col < 0) or (ColOrder[I].col >= Grid.ColCount) then
      Exit;

  if Fixed then
    FirstRow := 0
  else
    FirstRow := Grid.FixedRows;

  J := FirstRow;
  Sorted := True;
  repeat
    Inc(J);
    for I := FirstRow to Grid.RowCount - 2 do
      if Sort(I, I + 1) > 0 then
      begin
        TMoveSG(Grid).MoveRow(i + 1, i);
        Sorted := False;
      end;
  until Sorted or (J >= Grid.RowCount + 1000);
  Grid.Repaint;
end;


end.
